import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;

/**
 * Created by LuoTao on 2016/10/25.
 * LemonTech Copyright reserved.
 */
public class PDFHelper {

    private static Logger log = LogManager.getLogger(PDFHelper.class);
    private static BaseFont defaultFont;
    private Map<query, Table> resultTable;
    private Font textFont;
    private Font title1Font;
    private Font title2Font;
    private MonitorConfig config;

    /**
     * 初始化PDF文档各种属性
     *
     * @param fileName PDF文件名
     */
    public void write(String fileName, MonitorConfig config, Map<query, Table> resultTable) {
        this.resultTable = resultTable;
        this.config = config;
        Document toWrite = new Document(PageSize.A3);
        toWrite.addAuthor(config.getAuthor());
        toWrite.addTitle(config.getTitle());
        toWrite.addCreationDate();
        toWrite.addLanguage("Chinese");
        try {
            defaultFont = BaseFont.createFont("simkai.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        } catch (DocumentException e) {
            log.error("无法加载字体，中文可能无法正常显示");
            e.printStackTrace();
        } catch (IOException e) {
            log.error("找不到字体文件");
            e.printStackTrace();
        }
        textFont = new Font(defaultFont, 13);
        title1Font = new Font(defaultFont, 17, Font.BOLD);
        title2Font = new Font(defaultFont, 15, Font.BOLD);
        PdfWriter pdfWriter = null;
        try {
            pdfWriter = PdfWriter.getInstance(toWrite, new FileOutputStream(fileName));
        } catch (DocumentException e) {
            log.error("PDF文件初始化错误");
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        //配置页码
        Rectangle rect = new Rectangle(36, 54, 559, 788);
        rect.setBorderColor(BaseColor.GRAY);
        pdfWriter.setBoxSize("art", rect);
        pdfWriter.setPageEvent(new pageFoot());
        toWrite.open();
        insertAllDBQueries(toWrite);
        toWrite.close();
    }

    /**
     * 插入所有数据库的结果
     *
     * @param pdfDoc pdf文档
     */
    private void insertAllDBQueries(Document pdfDoc) {
        boolean isFirstPage = true;
        for (Config dbConfig : config.getConfigList()) {
            if (isFirstPage) {
                isFirstPage = false;
            } else {
                pdfDoc.newPage();
            }
            try {
                pdfDoc.add(new Paragraph("数据库名称：" + dbConfig.getDBalias(), title1Font));
                log.info(dbConfig.getDBalias() + "插入开始");
                insertAllQueryResult(pdfDoc, dbConfig.getQueryList());
                log.info(dbConfig.getDBalias() + "插入完成");
            } catch (DocumentException e) {
                log.warn("数据插入PDF失败");
                e.printStackTrace();
            }
        }
    }

    /**
     * 插入当前数据库中所有的查询结果
     *
     * @param pdfDoc pdf文档
     */
    private void insertAllQueryResult(Document pdfDoc, java.util.List<query> queryList) {
        BaseFont tmpFont;
        try {
            tmpFont = BaseFont.createFont("msyh.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        } catch (DocumentException | IOException e) {
            log.warn("微软雅黑字体加载失败，将使用默认字体");
            tmpFont = defaultFont;
            e.printStackTrace();
        }
        Font commentFont = new Font(tmpFont, 9, Font.ITALIC, BaseColor.RED);
        for (query m_query : queryList) {
            try {
                pdfDoc.add(new Paragraph("当前查询名称：" + m_query.getName(), title2Font));
                pdfDoc.add(new Paragraph("注：" + m_query.getNote(), commentFont));
                //插入当前query的变量
                if (m_query.getVars() != null && m_query.getVars().size() != 0) {
                    pdfDoc.add(new Paragraph("当前查询有如下变量：", textFont));
                    Map<String, String> vars = m_query.getVars();
                    for (Map.Entry<String, String> var : vars.entrySet()) {
                        pdfDoc.add(new Paragraph(String.format("%s:%s", var.getKey(), var.getValue()), textFont));
                    }
                }
                pdfDoc.add(new Paragraph("\n"));
                log.info(m_query.getName() + "插入开始");
                insertQueryResult(pdfDoc, m_query.getName(), resultTable.get(m_query));
                log.info(m_query.getName() + "插入完成");
            } catch (DocumentException e) {
                log.warn("表格插入失败");
                e.printStackTrace();
            }

        }
    }

    /**
     * 插入一个查询的结果
     *
     * @param pdfDoc      pdf文档
     * @param resultTable 查询结果的表格数据
     */
    private void insertQueryResult(Document pdfDoc, String queryName, Table resultTable) {
        //配置字号以及样式（斜体等）
        Font tableFont = new Font(defaultFont, 11);
        //创建指定列数的表格
        PdfPTable toInsertTable;
        try {
            toInsertTable = new PdfPTable(resultTable.getColumnNums());
        } catch (Exception e) {
            log.warn(queryName + "表格数据错误，无法写入PDF");
            e.printStackTrace();
            return;
        }
        //配置表格的占用比例
        toInsertTable.setWidthPercentage(100);
        //设置为中央对齐
        toInsertTable.setHorizontalAlignment(PdfPTable.ALIGN_CENTER);
        PdfPCell tableHeader = new PdfPCell();
        //配置表头颜色
        tableHeader.setBackgroundColor(new BaseColor(255, 250, 205));
        //表头居中对齐
        tableHeader.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
        //表头名称
        for (String m_header : resultTable.getHeader()) {
            tableHeader.setPhrase(new Paragraph(m_header, tableFont));
            toInsertTable.addCell(tableHeader);
        }
        //正文部分
        PdfPCell tableContent = new PdfPCell();
        //中央居中对齐
        tableContent.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
        tableContent.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
        //表格内容填充
        String[] rowData;
        boolean rowEven = false;
        BaseColor evenColor = new BaseColor(230, 230, 255);
        BaseColor oddColor = BaseColor.WHITE;
        while ((rowData = resultTable.getNext()) != null) {
            for (String colData : rowData) {
                tableContent.setPhrase(new Paragraph(colData, tableFont));
                if (rowEven) {
                    tableContent.setBackgroundColor(evenColor);
                } else {
                    tableContent.setBackgroundColor(oddColor);
                }
                toInsertTable.addCell(tableContent);
            }
            rowEven = !rowEven;
        }
        try {
            //表格插入
            pdfDoc.add(toInsertTable);
        } catch (DocumentException e) {
            log.error("表格数据插入失败");
            e.printStackTrace();
        }
    }

    class pageFoot extends PdfPageEventHelper {
        @Override
        public void onEndPage(PdfWriter writer, Document document) {
            super.onEndPage(writer, document);
            Rectangle rect = writer.getBoxSize("art");
            ColumnText.showTextAligned(
                    writer.getDirectContent(),
                    Element.ALIGN_CENTER,
                    new Phrase(String.format("第%d页", writer.getPageNumber()), textFont),
                    (rect.getLeft() + rect.getRight()) / 2 + 120, rect.getBottom() - 40, 0);

        }
    }

}
